package cn.venny.qiniu.service.impl;

import cn.venny.qiniu.properties.QiNiuProperties;
import cn.venny.qiniu.service.QiNiuUploadService;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

/**
 * @author : Vick C
 * @version : v1.0
 * 2020/6/19
 */
public class DefaultQiNiuUploadServiceImpl implements QiNiuUploadService {

    /** 日志 */
    public static Logger log = LoggerFactory.getLogger(QiNiuUploadService.class);
    private static final String CHINESE_PATTERN = "[\u4E00-\u9FA5|\uFF01|\uFF0C|\u3002|\uFF08|\uFF09|\u300A|\u300B|\u201C|\u201D|\uFF1F|\uFF1A|\uFF1B|\u3010|\u3011]";

    private Auth auth;
    private QiNiuProperties properties;
    private UploadManager uploadManager;
    private BucketManager bucketManager;

    public DefaultQiNiuUploadServiceImpl() {
    }

    public DefaultQiNiuUploadServiceImpl(Auth auth, QiNiuProperties properties, UploadManager uploadManager, BucketManager bucketManager) {
        this.auth = auth;
        this.properties = properties;
        this.uploadManager = uploadManager;
        this.bucketManager = bucketManager;
    }

    @Override
    public void upload(String finalKey, InputStream in) {
        try {

            Response response = uploadManager.put(in, in.available(), finalKey, auth.uploadToken(properties.getBucket()), new StringMap(), null, true);

            if (log.isDebugEnabled()) {
                log.debug("upload {},fileSize:{},response:{}", finalKey, in.available(), response);
            }

            if (200 == response.statusCode) {
                return;
            }

            throw new RuntimeException(response.getInfo());
        } catch (IOException e) {

            if (log.isErrorEnabled()) {
                log.error("upload image/video to qi niu cloud has error", e);
            }

            throw new RuntimeException("upload image/ video to qiniu cloud has error,[ " + e.getMessage() + " ]");
        }
    }

    @Override
    public void upload(final byte[] data, final String key) {
        try {
            Response response = uploadManager.put(data, key, auth.uploadToken(properties.getBucket()), new StringMap(), null, true);

            if (log.isDebugEnabled()) {
                log.debug("upload {},fileSize:{},response:{}", key, data.length, response);
            }

            if (200 == response.statusCode) {
                return;
            }

            throw new RuntimeException(response.getInfo());
        } catch (IOException e) {

            if (log.isErrorEnabled()) {
                log.error("upload image/video to qi niu cloud has error", e);
            }

            throw new RuntimeException("upload image/ video to qiniu cloud has error,[ " + e.getMessage() + " ]");
        }
    }

    @Override
    public String download(String key) {
        return download(key, 3600);
    }

    @Override
    public String download(String key, long expire) {
        // 绑定域名
        String domainOfBucket = properties.getCname();
        String publicUrl = String.format("%s/%s", domainOfBucket, key);
        String finalUrl = auth.privateDownloadUrl(publicUrl, expire);
        if (log.isDebugEnabled()) {
            log.debug("the file url is : {}", finalUrl);
        }
        return finalUrl;
    }

    @Override
    public String publicDownload(String fileName) {
        try {
            String encodedFileName = URLEncoder.encode(fileName, "utf-8").replace("+", "%20");
            return String.format("%s/%s", properties.getCname(), encodedFileName);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("encode error , origin:[" + fileName + "]");
        }
    }

    @Override
    public void delete(String key) {
        try {
            Response response = bucketManager.delete(properties.getBucket(), key);

            if (log.isDebugEnabled()) {
                log.debug("delete file {} response {}", key, response);
            }
            if (200 == response.statusCode) {
                return;
            }

            throw new RuntimeException(response.getInfo());
        } catch (IOException e) {

            if (log.isErrorEnabled()) {
                log.error("delete image/video has error", e);
            }

            throw new RuntimeException("delete image/video has error,[ " + e.getMessage() + " ]");
        }
    }

    @Override
    public String getToken() {
        return auth.uploadToken(properties.getBucket());
    }
}
